package com.tan.lbs.overlay;



import java.util.ArrayList;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.widget.Toast;

import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;
import com.tan.lbs.NPCGreetingActivity;
import com.tan.lbs.QuestsTabActivity;
import com.tan.lbs.dao.ItemDAO;
import com.tan.lbs.dao.QuestDAO;
import com.tan.lbs.dao.impl.ItemDAOImpl;
import com.tan.lbs.dao.impl.QuestDAOImpl;
import com.tan.lbs.entity.Condition;
import com.tan.lbs.entity.GameRuleManager;
import com.tan.lbs.entity.Item;
import com.tan.lbs.entity.NPC;
import com.tan.lbs.entity.Quest;
import com.tan.lbs.util.Constants;


public class GameOverlay extends ItemizedOverlay<OverlayItem>{

	private ArrayList<OverlayItem> overlayItems = new ArrayList<OverlayItem>();
	private Context context;
	private Location playerLocation;
	private MapView mapView;
	//Only within 25 meters can the player interact with objects on the map
	public static final int AVAILABLE_INTERACT_DISTANCE = 1000000000;
	

	public GameOverlay(Drawable defaultMarker,Context context,Location playerLocation){
		super(boundCenterBottom(defaultMarker));
		this.context = context;
		this.playerLocation = playerLocation;
		populate();// this fix the bug in google API
	}
	public GameOverlay(Drawable defaultMarker) {
		super(boundCenterBottom(defaultMarker));
	}

	public void addOverlay(OverlayItem overlayItem){
		overlayItems.add(overlayItem);
		populate();
	}

	public void removeOverlay(OverlayItem overlayItem){
		overlayItems.remove(overlayItem);
		//bug fix
		setLastFocusedIndex(-1);
		populate();
	}
	
	public void removeAllOverlay(){
		overlayItems.clear();
		populate();
	}

	@Override
	protected OverlayItem createItem(int i) {

		return overlayItems.get(i);
	}
	
	public void setMapView(MapView view) {
		this.mapView = view;
	}
	

	@Override
	public int size() {

		return overlayItems.size();
	}

	@Override
	protected boolean onTap(int index) {
		final GameElementOverlayItem element = (GameElementOverlayItem)overlayItems.get(index);
		if(element.getElementType() == GameElementOverlayItem.NPC_ELE) {
			double latitude = element.getPoint().getLatitudeE6() / 1E6;
			double longitude = element.getPoint().getLongitudeE6() / 1E6;
			Location objectLocation = new Location("");
			objectLocation.setLatitude(latitude);
			objectLocation.setLongitude(longitude);
			if(isAvailableForInteraction(playerLocation,objectLocation,AVAILABLE_INTERACT_DISTANCE)) {
				NPC npc = (NPC)element.getLinkElement();
				Intent intent = new Intent();
				intent.putExtra("name",npc.getName());
				intent.putExtra("greet",npc.getGreeting());
				intent.putExtra("npcID",npc.getNpcID());
				intent.putExtra("iconID",npc.getIconID());
				intent.putExtra("startDialogNodeID",npc.getDialogID());
			    intent.setClass(context, NPCGreetingActivity.class);
			    context.startActivity(intent);
			} else {
				Toast.makeText(context, "Too far to talk to the person.", Toast.LENGTH_LONG).show();
			}
			
		} else if(element.getElementType() == GameElementOverlayItem.QUEST_ELE) {
			double latitude = element.getPoint().getLatitudeE6() / 1E6;
			double longitude = element.getPoint().getLongitudeE6() / 1E6;
			Location objectLocation = new Location("");
			objectLocation.setLatitude(latitude);
			objectLocation.setLongitude(longitude);
			if(isAvailableForInteraction(playerLocation,objectLocation,AVAILABLE_INTERACT_DISTANCE)) {
				final Quest quest = (Quest)element.getLinkElement();
				AlertDialog.Builder builder = new AlertDialog.Builder(context);
				builder.setMessage(
						"Check in this quest?")
						.setCancelable(false)
						.setPositiveButton("Check in",
								new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog, int id) {
										if(quest.getStatus().equals(Quest.COMPLETE_STATUS)) {
											Toast.makeText(context, "You've already finished the quest.", Toast.LENGTH_LONG).show();
										} else if(quest.getStatus().equals(Quest.NOT_CHECKED_IN_STATUS)) {
											int finishHighestOrder  = context.getSharedPreferences(Constants.PREFS_NAME, 0).getInt("highestAvailableQuest", 0);
											if(finishHighestOrder + 1 == quest.getQuestOrder()) {
												Toast.makeText(context, "Quest" + quest.getQuestOrder() + " starts now.", Toast.LENGTH_LONG).show();
												QuestDAO questDAO = new QuestDAOImpl(context);
												questDAO.updateQuestStatus(quest.getQuestID(),Quest.START_STATUS);
												 quest.setStatus(Quest.START_STATUS);
												GameRuleManager.getInstance(context, context.getSharedPreferences(Constants.PREFS_NAME, 0).getString("currentGameID", "")).gameRuleCheck(quest.getQuestID(),Condition.START_QUEST_CONDITION);
											} else {
												Toast.makeText(context, "You cannot start this request because you haven't finish the previous ones.", Toast.LENGTH_LONG).show();
											}
										} else if (quest.getStatus().equals(Quest.START_STATUS)){
											Toast.makeText(context, "The quest is already started.", Toast.LENGTH_LONG).show();
										}
									}
								});
				builder.setNegativeButton("Leave away",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {
								dialog.cancel();
							}
						});
				AlertDialog alert = builder.create();
				alert.show();
			} else {
				Toast.makeText(context, "Too far to check in the quest", Toast.LENGTH_LONG).show();
			}
		} else if(element.getElementType() == GameElementOverlayItem.ITEM_ELE) {
			double latitude = element.getPoint().getLatitudeE6() / 1E6;
			double longitude = element.getPoint().getLongitudeE6() / 1E6;
			Location objectLocation = new Location("");
			objectLocation.setLatitude(latitude);
			objectLocation.setLongitude(longitude);
			if(isAvailableForInteraction(playerLocation,objectLocation,AVAILABLE_INTERACT_DISTANCE)) {
				final Item item = (Item)element.getLinkElement();
				AlertDialog.Builder builder = new AlertDialog.Builder(context);
				builder.setMessage(
						"Pick up this item?")
						.setCancelable(false)
						.setPositiveButton("Pick up",
								new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog, int id) {
										// read status from DB
										ItemDAO itemDAO = new ItemDAOImpl(context);
										String itemStatus = itemDAO.readItemStatus(item.getItemID());
										if(itemStatus.equals(Item.NOT_PICKABLE)) {
											Toast.makeText(context, "You have to unlock something to pick up this.", Toast.LENGTH_LONG).show();
										} else if(itemStatus.equals(Item.PICKABLE)) {
											item.setStatus(Item.PICKED);
											
											itemDAO.updateItemStatus(item.getItemID(), Item.PICKED);

											GameRuleManager.getInstance(context, context.getSharedPreferences(Constants.PREFS_NAME, 0).getString("currentGameID", "")).gameRuleCheck(item.getItemID(),Condition.PICK_ITEM_CONDITION);
											
											GameOverlay.this.removeOverlay(element);
											mapView.invalidate();
										}
									}
								});
				builder.setNegativeButton("Leave away",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {
								dialog.cancel();
							}
						});
				AlertDialog alert = builder.create();
				alert.show();
			} else {
				Toast.makeText(context, "Too far to pick up the item", Toast.LENGTH_LONG).show();
			}
		}
		
		return true;
	}
	
	
	 public boolean isAvailableForInteraction(Location playerLocation, Location objectLocation, double checkDistance) {
		 if(checkDistance <= 10) checkDistance = 10;
		 return playerLocation.distanceTo(objectLocation) < checkDistance;  
	 }


}
